package mop.model.task.state;

import java.util.Date;
import java.util.Map;

import mop.exception.BusinessRule2Exception;
import mop.exception.BusinessRule3Exception;
import mop.model.World;
import mop.model.task.Task;
import mop.model.task.TaskInterface;

/**
 * State class for a successful task
 * 
 * @author 	MOP Team 7
 */
public class Successful extends State
{

	/**
	 * Constructor
	 * @param t	Task for this state
	 * @post	Task is set to given task
	 * 	|super(t)
	 * 
	 * @throws BusinessRule2Exception
	 *     | @see rule2isMet
	 * 
	 * @throws BusinessRule3Exception
	 * 	   | @see rule3isMet
	 */
	public Successful(Task t) throws BusinessRule2Exception, BusinessRule3Exception
	{
		super(t);
		
		TaskInterface problem = rule2isMet();
		
		if(problem != null)
		{
			throw new BusinessRule2Exception(problem);
		}
		
		if(rule3isMet() == false)
		{
			throw new BusinessRule3Exception(this.getTask());
		}
	}
	
	/**
	 * Constructor without exceptions !! 
	 * @param t Task for this state
	 * @param ignore boolean that tells us whether it's a forced construction
	 */
	public Successful(Task t,boolean ignore)
	{
		super(t,ignore);
	}

	/**
	 * Copy Constructor
	 * @param oldstate
	 */
	public Successful(State oldstate) 
	{
		super(oldstate);
	}
	
	
	/***************************************************************************
	 * 						Status
	 ***************************************************************************/	

	/**
	 * Use Case functionality
	 * Update details of task according to this state
     * @return returns false when details should not be updated
	 */
	public boolean updateDetails()
	{
		return false;
	}
	
	
	/**
	 * Refresh the status 
	 * Correct Business Rule 2 and 3
	 * 
	 * @return the new state : this can be Successful or failed or Unfinished
	 */
	public State refreshStatus()
	{
		try
		{
			return StateFactory.createState(stateName(),this.getTask());
		}
		catch ( BusinessRule2Exception e)
		{
			return StateFactory.createUncheckedState(Failed.stateName(),this.getTask());
		}
		catch (BusinessRule3Exception e)
		{
			return StateFactory.createUncheckedState(Failed.stateName(),this.getTask());
		}
	}
	
	/**
	 * Return whether business rule 3 is met
	 * @return This is false if current time is smaller than start
	 */
	public boolean rule3isMet()
	{
		Date now = World.getTime();
		
		if(getTask().getSchedule().getStart().after(now))
		{
			return false;
		}
		return true;
	}
		
	/**
	 * Return problem cases when setting a state to Failed or Unfinished
	 * @return null Successful never ruins anything
	 */
	protected Map<String,String> rule2Parents()
	{
		return null;
	}
	
	/***************************************************************************
	 * 						Java object interface
	 ***************************************************************************/
	/**
	 * @see 	Object#toString()
	 */
	public String toString()
	{
		return "Successful";
	}
	/**
	 * Return a string of the class name
	 * @return "Successful"
	 */
	public static String stateName()
	{
		return "Successful";
	}
}
